#include <boost/math/distributions/binomial.hpp>


class Binomial : public Distribution
{
	public:
	Binomial(){}



	Binomial(int n,double p, double d)
	{
		_n=d;
		boost::random::binomial_distribution<>B(n,p);
		bin=new boost::math::binomial_distribution<> (n,p);
		rbin =new RandomG::Random<boost::random::binomial_distribution<> >(B);
		boost::random::uniform_01<> U;
		runif=new RandomG::Random<boost::random::uniform_01<> >(U);
		_p=p;
	}
	virtual ~Binomial()
	{
		delete rbin;
		delete bin;
	}

	mat r(int j)
	{
		mat X(_n,1);
		for(int i=0;i<_n;i++)
		{
		 	X(i,0)=(*rbin)();
		}
		return X;
	}
	double Rbin(void)
	{
		double res=0;
		if((*runif)()<_p)
		{
			res=1;
		}
		return res;
	}
	mat scrambled(int N)
	{
		mat B(N,_n);
		for(int i=0;i<N;i++)
		{
			B(i,span::all)=(this->r(1)).t();
		}
		return B;
	}


	double 	d(mat x,int i=0,int kk=0){
		int p=x.n_elem;
		double res=1;
		for(int j=0;j<p;j++)
		{
			if(x(j,0)==1)
			{
				res*=_p;
			}else{
				res*=1-_p;
			}
			//res*=pdf(*bin,(int)x(j,0));
		}
		if(i==0){
			return res;
		}else{
			return log(res);
		}
	}
	mat Var(mat X){return arma::cov(X);}
	void Set_n(int n){	_n=n;	}
	void Set_m(mat m){	_m=m;	}
	void Set_s(mat s){	_s=s;}
	mat Get_s(void){return _s;}
	mat Get_m(void){return _m;}
	private:
	int _n;
	mat _m;
	mat _s;
	double _p;
	mat _is;
	mat _cs;
	RandomG::Random<boost::random::uniform_01<> > *runif;
	boost::math::binomial_distribution<> *bin;
	RandomG::Random<boost::random::binomial_distribution<> > *rbin;

};

